<template>
  <div class="color-challenge">
    <h1 class="game-title">网格染色挑战</h1>
    
    <!-- 游戏信息面板 -->
    <div class="game-info">
      <div class="info-item">
        <span class="info-label">剩余步数:</span>
        <span class="info-value steps">{{ stepsLeft }}</span>
      </div>
      <div class="info-item">
        <span class="info-label">目标颜色:</span>
        <div class="target-color-display" :style="{ backgroundColor: targetColor }"></div>
      </div>
      <div class="info-item">
        <span class="info-label">难度:</span>
        <select v-model="difficulty" @change="changeDifficulty" class="difficulty-select">
          <option value="easy">简单 ({{ difficultySettings.easy }}步)</option>
          <option value="medium">中等 ({{ difficultySettings.medium }}步)</option>
          <option value="hard">困难 ({{ difficultySettings.hard }}步)</option>
        </select>
      </div>
    </div>

    <!-- 颜色选择器 -->
    <div class="color-picker">
      <div 
        v-for="color in colors" 
        :key="color"
        class="color-option"
        :class="{ selected: selectedColor === color }"
        :style="{ backgroundColor: color }"
        @click="selectColor(color)"
      ></div>
    </div>

    <!-- 游戏网格 -->
    <div class="game-grid">
      <div 
        v-for="(row, rowIndex) in grid" 
        :key="`row-${rowIndex}`"
        class="grid-row"
      >
        <div 
          v-for="(cell, colIndex) in row" 
          :key="`cell-${rowIndex}-${colIndex}`"
          class="grid-cell"
          :class="{ 'grid-cell-stone': cell.isStone }"
          :style="{
            backgroundColor: cell.color,
            animation: cell.isAnimating ? 'colorChange 0.5s ease' : 'none',
            '--from-color': cell.animationFrom || cell.color,
            '--to-color': cell.color
          }"
          @click="handleCellClick(rowIndex, colIndex)"
        ></div>
      </div>
    </div>

    <!-- 控制按钮 -->
    <div class="game-controls">
      <button @click="resetGame" class="control-btn reset-btn">
        重新开始
      </button>
    </div>

    <!-- 游戏结果弹窗 -->
    <div v-if="gameOver" class="game-over-modal">
      <div class="modal-content">
        <h2>{{ isWinner ? '恭喜你赢了！' : '游戏结束，步数用尽！' }}</h2>
        <p v-if="isWinner">你在 {{ 15 - stepsLeft }} 步内完成了挑战！</p>
        <p v-else>再接再厉，尝试更简单的难度吧！</p>
        <button @click="closeModal" class="modal-btn">确定</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'

// 游戏配置
const gridSize = { rows: 8, cols: 10 }
const colors = ['red', 'blue', 'green', 'yellow']
// 难度设置将在resetGame时动态计算
const difficultySettings = {
  easy: 15,
  medium: 12,
  hard: 8
}
// 石头色块设置
const STONE_COLOR = '#333333' // 石头颜色
const STONE_COUNT_PERCENTAGE = 0.15 // 石头占总格子的百分比（15%）

// 游戏状态
const grid = ref([])
const targetColor = ref('')
const selectedColor = ref('')
const stepsLeft = ref(15)
const gameOver = ref(false)
const isWinner = ref(false)
const difficulty = ref('medium')

// 初始化网格 - 增强趣味性版本，包含石头色块
function initGrid() {
  // 先创建空白网格
  const newGrid = new Array(gridSize.rows).fill().map(() => 
    new Array(gridSize.cols).fill().map(() => ({
      color: null,
      isAnimating: false,
      animationFrom: null,
      isStone: false // 标记是否为石头色块
    }))
  )
  
  // 使用区域生成算法，创建更大更集中的色块
  const totalCells = gridSize.rows * gridSize.cols
  const regions = []
  
  // 随机选择每个颜色的区域大小，确保总和不超过总格子数
  const minRegionSize = 15 // 增加最小区域大小
  const maxRegionSize = Math.floor(totalCells / colors.length * 1.5) // 允许较大的区域变化
  const regionSizes = new Map()
  let remainingCells = totalCells
  
  // 为每种颜色分配区域大小
  colors.forEach(color => {
    const maxPossibleSize = Math.min(maxRegionSize, remainingCells - (colors.length - regionSizes.size - 1) * minRegionSize)
    const size = Math.floor(Math.random() * (maxPossibleSize - minRegionSize + 1)) + minRegionSize
    regionSizes.set(color, size)
    remainingCells -= size
  })
  
  // 对于剩余的格子，随机分配给现有颜色
  while (remainingCells > 0) {
    const randomColor = colors[Math.floor(Math.random() * colors.length)]
    regionSizes.set(randomColor, regionSizes.get(randomColor) + 1)
    remainingCells--
  }
  
  // 为每种颜色生成一个连通区域
  colors.forEach(color => {
    const size = regionSizes.get(color)
    
    // 随机选择一个未被填充的起点
    let startRow, startCol
    do {
      startRow = Math.floor(Math.random() * gridSize.rows)
      startCol = Math.floor(Math.random() * gridSize.cols)
    } while (newGrid[startRow][startCol].color !== null)
    
    // 使用BFS生成连通区域
    const queue = [{row: startRow, col: startCol}]
    newGrid[startRow][startCol].color = color
    let filledCount = 1
    
    // 打乱方向顺序，使区域形状更自然
    const directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    
    while (queue.length > 0 && filledCount < size) {
      // 优先扩展外部边缘，使区域更集中
      const shuffledQueue = [...queue].sort(() => Math.random() - 0.5)
      const currentQueue = queue.splice(0)
      
      for (const {row, col} of shuffledQueue) {
        // 再次打乱方向
        const shuffledDirections = [...directions].sort(() => Math.random() - 0.5)
        
        for (const [dr, dc] of shuffledDirections) {
          const r = row + dr
          const c = col + dc
          
          if (r >= 0 && r < gridSize.rows && c >= 0 && c < gridSize.cols && newGrid[r][c].color === null) {
            newGrid[r][c].color = color
            filledCount++
            queue.push({row: r, col: c})
            
            if (filledCount >= size) break
          }
        }
        
        if (filledCount >= size) break
      }
    }
    
    // 如果还没填满，就随机填充剩余格子
    while (filledCount < size) {
      const randomRow = Math.floor(Math.random() * gridSize.rows)
      const randomCol = Math.floor(Math.random() * gridSize.cols)
      
      if (newGrid[randomRow][randomCol].color === null) {
        newGrid[randomRow][randomCol].color = color
        filledCount++
      }
    }
  })
  
  // 添加石头色块
  const totalStones = Math.floor(gridSize.rows * gridSize.cols * STONE_COUNT_PERCENTAGE)
  let stonesAdded = 0
  
  while (stonesAdded < totalStones) {
    const randomRow = Math.floor(Math.random() * gridSize.rows)
    const randomCol = Math.floor(Math.random() * gridSize.cols)
    
    // 确保这个格子不是起点，并且不是已经被设置为石头的格子
    if (newGrid[randomRow][randomCol].color !== null && !newGrid[randomRow][randomCol].isStone) {
      // 保存原始颜色（虽然石头不会变色，但保留以防未来需要）
      const originalColor = newGrid[randomRow][randomCol].color
      newGrid[randomRow][randomCol].color = STONE_COLOR
      newGrid[randomRow][randomCol].isStone = true
      stonesAdded++
    }
  }
  
  grid.value = newGrid
}

// 估算完成游戏所需的最少步数
function estimateMinSteps() {
  // 简单的估算算法：计算需要消除的不同颜色连通块的数量
  const visited = new Set()
  let regions = 0
  
  // 排除石头和目标颜色
  for (let row = 0; row < gridSize.rows; row++) {
    for (let col = 0; col < gridSize.cols; col++) {
      const cell = grid.value[row][col]
      const cellKey = `${row},${col}`
      
      // 跳过石头、目标颜色或已访问的单元格
      if (cell.isStone || cell.color === targetColor.value || visited.has(cellKey)) {
        continue
      }
      
      // 使用BFS计算连通区域
      const queue = [{row, col}]
      visited.add(cellKey)
      const currentColor = cell.color
      
      while (queue.length > 0) {
        const {row: r, col: c} = queue.shift()
        
        // 四向检查
        const directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
        for (const [dr, dc] of directions) {
          const nr = r + dr
          const nc = c + dc
          const neighborKey = `${nr},${nc}`
          
          if (nr >= 0 && nr < gridSize.rows && nc >= 0 && nc < gridSize.cols &&
              !visited.has(neighborKey) && !grid.value[nr][nc].isStone &&
              grid.value[nr][nc].color === currentColor) {
            visited.add(neighborKey)
            queue.push({row: nr, col: nc})
          }
        }
      }
      
      regions++
    }
  }
  
  // 基础估算步数 = 区域数 + 1（一个安全系数）
  // 确保最小步数合理
  const minSteps = Math.max(regions + 1, 3)
  return minSteps
}

// 选择颜色
function selectColor(color) {
  if (gameOver.value) return
  selectedColor.value = color
}

// 处理格子点击
async function handleCellClick(row, col) {
  if (gameOver.value || !selectedColor.value || stepsLeft.value <= 0) return
  
  // 如果点击的是石头色块，不做任何操作
  if (grid.value[row][col].isStone) return
  
  const originalColor = grid.value[row][col].color
  if (selectedColor.value === originalColor) return
  
  stepsLeft.value--
  
  // 使用洪水填充算法染色
  await floodFill(row, col, originalColor, selectedColor.value)
  
  // 检查胜利条件
  checkWinCondition()
}

// 洪水填充算法（带动画效果）
async function floodFill(row, col, originalColor, newColor) {
  if (row < 0 || row >= gridSize.rows || col < 0 || col >= gridSize.cols) return
  if (grid.value[row][col].color !== originalColor || grid.value[row][col].isStone) return
  
  // 设置动画属性
  grid.value[row][col].animationFrom = originalColor
  grid.value[row][col].isAnimating = true
  
  // 延迟一小段时间以显示动画
  await new Promise(resolve => setTimeout(resolve, 30))
  
  // 更新颜色
  grid.value[row][col].color = newColor
  
  // 等待动画完成
  await nextTick()
  
  // 关闭动画状态
  setTimeout(() => {
    grid.value[row][col].isAnimating = false
    grid.value[row][col].animationFrom = null
  }, 500)
  
  // 四向扩散
  await Promise.all([
    floodFill(row + 1, col, originalColor, newColor),
    floodFill(row - 1, col, originalColor, newColor),
    floodFill(row, col + 1, originalColor, newColor),
    floodFill(row, col - 1, originalColor, newColor)
  ])
}

// 检查胜利条件
function checkWinCondition() {
  // 检查所有非石头色块是否都匹配目标颜色
  const allMatchTarget = grid.value.every(row => 
    row.every(cell => cell.isStone || cell.color === targetColor.value)
  )
  
  if (allMatchTarget) {
    gameOver.value = true
    isWinner.value = true
  } else if (stepsLeft.value <= 0) {
    gameOver.value = true
    isWinner.value = false
  }
}

// 重置游戏
function resetGame() {
  initGrid()
  targetColor.value = colors[Math.floor(Math.random() * colors.length)]
  selectedColor.value = ''
  
  // 估算完成游戏所需的最少步数
  const minSteps = estimateMinSteps()
  
  // 根据难度调整总步数
  switch (difficulty.value) {
    case 'easy':
      difficultySettings.easy = minSteps + 2
      break
    case 'medium':
      difficultySettings.medium = minSteps + 1
      break
    case 'hard':
      difficultySettings.hard = minSteps
      break
  }
  
  // 设置剩余步数
  stepsLeft.value = difficultySettings[difficulty.value]
  gameOver.value = false
  isWinner.value = false
}

// 关闭弹窗
function closeModal() {
  gameOver.value = false
  resetGame()
}

// 更改难度
function changeDifficulty() {
  resetGame()
}

// 组件挂载时初始化游戏
onMounted(() => {
  resetGame()
})
</script>

<style scoped>
.color-challenge {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-family: 'Arial', sans-serif;
}

.game-title {
  font-size: 2.5rem;
  margin-bottom: 20px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
  animation: fadeIn 1s ease-in-out;
}

.game-info {
  display: flex;
  gap: 30px;
  margin-bottom: 20px;
  background: rgba(255, 255, 255, 0.1);
  padding: 15px 25px;
  border-radius: 10px;
  backdrop-filter: blur(10px);
}

.info-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.info-label {
  font-weight: 500;
  font-size: 1.1rem;
}

.info-value {
  font-weight: bold;
  font-size: 1.2rem;
}

.steps {
  color: #ffeb3b;
}

.target-color-display {
  width: 30px;
  height: 30px;
  border-radius: 5px;
  border: 2px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

.difficulty-select {
  padding: 5px 10px;
  border-radius: 5px;
  border: none;
  background: white;
  font-size: 1rem;
  cursor: pointer;
}

.color-picker {
  display: flex;
  gap: 15px;
  margin-bottom: 25px;
}

.color-option {
  width: 60px;
  height: 60px;
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 3px solid transparent;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}

.color-option:hover {
  transform: scale(1.1);
  box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3);
}

.color-option.selected {
  transform: scale(1.15);
  border-color: white;
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
}

.game-grid {
  background: rgba(255, 255, 255, 0.1);
  padding: 15px;
  border-radius: 15px;
  backdrop-filter: blur(5px);
  margin-bottom: 25px;
}

.grid-row {
  display: flex;
  gap: 2px;
  margin-bottom: 2px;
}

.grid-row:last-child {
  margin-bottom: 0;
}

.grid-cell {
  width: 50px;
  height: 50px;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.2);
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

.grid-cell:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}

/* 石头色块样式 */
.grid-cell-stone {
  background-image: linear-gradient(45deg, #2c2c2c 25%, transparent 25%),
                    linear-gradient(-45deg, #2c2c2c 25%, transparent 25%),
                    linear-gradient(45deg, transparent 75%, #2c2c2c 75%),
                    linear-gradient(-45deg, transparent 75%, #2c2c2c 75%);
  background-size: 10px 10px;
  background-position: 0 0, 0 5px, 5px -5px, -5px 0px;
  cursor: not-allowed;
  border: 2px solid #555;
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
}

.grid-cell-stone:hover {
  transform: none;
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
}

.control-btn {
  padding: 12px 30px;
  border: none;
  border-radius: 30px;
  font-size: 1.1rem;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
  background: white;
  color: #667eea;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.control-btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}

.game-over-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

.modal-content {
  background: white;
  color: #333;
  padding: 40px;
  border-radius: 15px;
  text-align: center;
  box-shadow: 0 10px 50px rgba(0, 0, 0, 0.3);
  animation: slideUp 0.5s ease;
}

.modal-content h2 {
  margin-bottom: 15px;
  font-size: 2rem;
  color: #667eea;
}

.modal-content p {
  margin-bottom: 30px;
  font-size: 1.1rem;
  color: #666;
}

.modal-btn {
  padding: 12px 30px;
  border: none;
  border-radius: 30px;
  font-size: 1.1rem;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
  background: #667eea;
  color: white;
}

.modal-btn:hover {
  background: #764ba2;
  transform: translateY(-2px);
}

/* 动画定义 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes colorChange {
  0% {
    background-color: var(--from-color);
    transform: scale(1);
  }
  50% {
    background-color: var(--to-color);
    transform: scale(1.1);
  }
  100% {
    background-color: var(--to-color);
    transform: scale(1);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .game-title {
    font-size: 2rem;
  }
  
  .game-info {
    flex-direction: column;
    gap: 15px;
    text-align: center;
  }
  
  .info-item {
    justify-content: center;
  }
  
  .grid-cell {
    width: 40px;
    height: 40px;
  }
  
  .color-option {
    width: 50px;
    height: 50px;
  }
}

@media (max-width: 576px) {
  .game-title {
    font-size: 1.8rem;
  }
  
  .grid-cell {
    width: 35px;
    height: 35px;
  }
  
  .color-picker {
    gap: 10px;
  }
  
  .color-option {
    width: 45px;
    height: 45px;
  }
}
</style>